package com.dap.dubbo.rpc.listener;

import com.alibaba.dubbo.common.extension.Activate;
import com.alibaba.dubbo.common.utils.StringUtils;
import com.alibaba.dubbo.rpc.Invoker;
import com.alibaba.dubbo.rpc.InvokerListener;
import com.alibaba.dubbo.rpc.RpcException;
import com.dap.dubbo.rpc.cache.RegisterCache;
import com.dap.dubbo.rpc.config.ParamConfig;
import com.dap.dubbo.rpc.config.ZkConfig;
import com.dap.dubbo.rpc.utils.ZkManager;
import com.dap.dubbo.rpc.utils.ZkNodeListener;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.net.InetAddress;
import java.util.List;

//@Activate
public class ZkInvokerListener implements InvokerListener,ZkNodeListener {
    /**
     * 跟目录
     */
    private String rootPath="/dap/rateLimit";

    private String endPrefix="/config";

    private Integer initLimit=1000;

    private ObjectMapper mapper = new ObjectMapper();

    @Override
    public void referred(Invoker<?> invoker) throws RpcException {
        try {

           ZkManager zkManager = ZkConfig.applicationContext.getBean(ZkManager.class);
           String resourceName = ZkInvokerListener.getResourceName(invoker);
           String watchPath = rootPath + "/" + resourceName + endPrefix;
           String pathIp=watchPath + "/" + InetAddress.getLocalHost().getHostName();
           /**
            * 如果根节点创建根节点
            */
           boolean root = zkManager.isExists(watchPath);
           if (root) {
               zkManager.create(pathIp,null, false);
               /**
                * 注册监听器
                */
               zkManager.childrenWatch(watchPath, this);
               zkManager.watch(watchPath, this);
           } else {
               zkManager.create(watchPath, mapper.writeValueAsString(new ParamConfig()), true);
               /**
                * 注册监听器
                */
               zkManager.childrenWatch(watchPath, this);
               zkManager.watch(watchPath, this);
               zkManager.create(pathIp, null, false);
           }
       }catch (Exception e){
            e.printStackTrace();
        }


    }

    @Override
    public void update(String path, String data) {
        ZkManager zkManager = ZkConfig.applicationContext.getBean(ZkManager.class);
        try {
            List<String> list=zkManager.getChildrenNode(path);
            if(!StringUtils.isEmpty(data)){
                ParamConfig config = mapper.readValue(data, ParamConfig.class);
                Integer total= config.getToken();
                if(list!=null && list.size()>0){
                    Integer c = total / list.size();
                    config.setToken(c);
                    String key= path.substring(rootPath.length()+1,path.length()-endPrefix.length());
                    RegisterCache.register(key,config);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void updateChildren(String path)  {
        ZkManager zkManager = ZkConfig.applicationContext.getBean(ZkManager.class);
        try {
            List<String> list=zkManager.getChildrenNode(path);
            String data=zkManager.getDataNode(path);
            if(!StringUtils.isEmpty(data)){
                ParamConfig config = mapper.readValue(data, ParamConfig.class);
                Integer total= config.getToken();
               if(list!=null && list.size()>0){
                   Integer c = total / list.size();
                   config.setToken(c);
                   String key= path.substring(rootPath.length()+1,path.length()-endPrefix.length());
                   RegisterCache.register(key,config);
               }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    @Override
    public void destroyed(Invoker<?> invoker) {

    }

    private static String getResourceName(Invoker<?> invoker) {
        StringBuilder buf = new StringBuilder(64);
        buf.append(invoker.getInterface().getName());
        return buf.toString();
    }
}
